iT邦幫忙

2022 iThome 鐵人賽

DAY 18
0
Modern Web

Hello TypeScript 菜鳥系列 第 18

Day 17. TypeScript interface 介面:extends、implements

  • 分享至 

  • xImage
  •  

Day 17 稍微認識interface進階一點點的用法


extends

extends 關鍵字是用來擴充一個 interface 描述的屬性,例如:

interface Person {
	first_name: string;
	last_name: string;
	birth_year: number;
}


interface SuperHero extends Person {
	title: string;
	ability: string;
}

const Kent: SuperHero = ('Clark', 'Kent', 1938, 'superman', 'fly');

範例的意思是,因為SuperHero也擁有Person所描述的first_name、last_name屬性,因此使用 extends 直接從延伸Person擁有的屬性。

這樣做的好處有幾個,假設SuperHero包含所有Person擁有的屬性,並且Person有十幾、二十個SuperHero也擁有的屬性:

  1. 若直接將SuperHero要新增的屬性 titleability 寫進Person,可能會影響指定Person為型別的物件 ─ 因為這個範例的邏輯是,SuperHero是Person的子集,將Person指定為型別的物件應該都不會有SuperHero的titleability 屬性。由此可知,SuperHero應該用extends去延伸、重複利用Person的屬性;
  2. 若是用extends 延伸Person的所有屬性,SuperHero就不用在自己的 interface 重寫一次這麼多個屬性;
  3. 有了2的優點,對於物件屬性來說也相對容易維護:例如某次開發 發現型別有錯誤,修改Person其中一個屬性的型別,就會連帶影響全部有extends Person的interface,而不用一個一個interface去修改屬性型別;

另外,一個 interface 也能使用 ,extends 好幾個 interfaces。

假設Clark Kent平常不當超人的時候,只是一家公司的普通員工,所以他會擁有某家公司的所有員工(Employee)屬性:

interface Person {
	first_name: string;
	last_name: string;
	birth_year: number;
}

interface Employee {
	eid: number;
	department: string;
	director: number;
	job: string;
	salary: number;
}

interface SuperHero extends Person, Employee {
	title: string;
	ability: string;
}


implements

Day 15講到類別(class)的時候有提到「類別可以用implements 關鍵字去實作interface的方法」。

意思是,interface只會事先定義類別所有可能會擁有的方法和屬性型別(即class表面上應該長什麼樣子),如下的Shape介面;而class則是能用 implements 關鍵字實際寫出方法的內容

舉一個比較簡單一點的例子,這裡讓Rectangle類別 implements Shape介面:

interface Shape {
	width: number;
	height: number;
	getArea() => number;
}

class Rectangle implements Shape {
	private width: number;
	private height: number;
	
	constructor(width: number, height: number){
		this.width = width;
		this.height = height;
	}
	
	getArea() {
		return this.width * this.height;
	};
}

有個有趣的事情是,interface也是能夠extends一個類別,但是只有這個被extends的類別和其子類別可以implemetns 這個interface,否則就會出錯。

接續前一個例子,這裡刻意定義了一個Triangle類別要實作的interface:

interface TriangleShape extends Rectangle {
	angles: [number, number, number];
}


class Triangle extends Rectangle implements TriangleShape {
	private width: number;
	private height: number;
	private angles: [number, number, number];
	
	constructor(width: number, height: number, angle: [number, number, number]){
		super(width, height);
		this.angle = angle;
	}
	
	getArea(){
		return this.width * this.height / 2;
	}
}


class Circle implements TriangleShape {};	// error

在這個範例裡,TriangleShape extends Rectangle類別,但是Circle類別不屬於Rectangle的子類別,所以沒辦法實作TriangleShape這個interface。


參考資料
TypeScript: JavaScript With Syntax For Types
TypeScript Tutorial


上一篇
Day 16. TypeScript interface 介面:基本語法
下一篇
Day 18. TypeScript Generic 泛型:超基本語法
系列文
Hello TypeScript 菜鳥31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言